package br.com.locasis.session;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.international.StatusMessages;
import org.jboss.seam.log.Log;
import org.jboss.seam.security.Credentials;
import org.jboss.seam.security.Identity;

import br.com.locasis.entity.Funcionalidade;
import br.com.locasis.entity.PerfilFuncionalidade;
import br.com.locasis.entity.Usuario;
import br.com.locasis.utilitarios.UtilString;

@Name("authenticator")
public class Authenticator {
	@Logger
	private Log log;

	@In
	Identity identity;
	@In
	Credentials credentials;
	@In
	EntityManager entityManager;
	@In
	LoginAuthenticator loginAuthenticator;
	
	@In(value = "statusMessages")
	protected StatusMessages messages;

	@Out(required = false, scope = ScopeType.SESSION)
	Usuario usuarioLogado;

	public boolean authenticate() {
		log.info("authenticating {0}", credentials.getUsername());
		// write your authentication logic here,
		// return true if the authentication was
		// successful, false otherwise
		if ("admin".equals(credentials.getUsername())
				&& "Locasis2012".equals(credentials.getPassword())) {
			identity.addRole("admin");
			List<Funcionalidade> funcionalidades = entityManager.createQuery(
					"select f from Funcionalidade f where f.flgAtivo is true")
					.getResultList();
			for (Funcionalidade f : funcionalidades) {
				identity.addRole(f.getNome() + "_EXCLUIR");
				identity.addRole(f.getNome() + "_GRAVAR");
				identity.addRole(f.getNome() + "_LER");
			}
			identity.addRole("GERENCIAR_USUARIOS");
			identity.addRole("FUNCIONALIDADES");

			return true;
		} else {
			try {
				Usuario user = (Usuario) entityManager
						.createQuery(
								"select u from Usuario u where u.login = :login and flgAtivo is true")
						.setParameter("login", credentials.getUsername())
						.getSingleResult();
				
				if(user.isFlgLogado()){
					messages.add("O usuário já encontra-se logado no sistema. Saia do sistema e após tente novamente.");
					return false;
				}
				if (user.getSenha().equals(
						UtilString.md5(credentials.getPassword()))) {
					user.getPerfil().getIdPerfil();
					usuarioLogado = user;
					loginAuthenticator.start(user.getLogin());
					atribuiPermissoes(user);
					user.setFlgLogado(true);
					entityManager.merge(user);
					entityManager.flush();
					return true;
				}
			} catch (NoResultException e) {
				return false;
			}
		}
		return false;
	}

	public void atribuiPermissoes(Usuario user) {
		List<PerfilFuncionalidade> listaPermissoes = entityManager
				.createQuery(
						"select pf from PerfilFuncionalidade pf where pf.perfil.idPerfil = :idPerfil")
				.setParameter("idPerfil", user.getPerfil().getIdPerfil())
				.getResultList();
		int contFunc = 0;
		int contUsuarios = 0;
		for (PerfilFuncionalidade pf : listaPermissoes) {
			if (pf.isFlgExclusao()) {
				identity.addRole(pf.getFuncionalidade().getNome() + "_EXCLUIR");
			}
			if (pf.isFlgGravacao()) {
				identity.addRole(pf.getFuncionalidade().getNome() + "_GRAVAR");
			}
			if (pf.isFlgLeitura()) {
				if (pf.getFuncionalidade().getNome()
						.equals("CADASTRAR_USUARIOS")
						|| pf.getFuncionalidade().getNome()
								.equals("CADASTRAR_PERFIS")) {
					contUsuarios++;
				} else {
					contFunc++;
				}
				identity.addRole(pf.getFuncionalidade().getNome() + "_LER");
			}
		}
		if (contUsuarios > 0) {
			identity.addRole("GERENCIAR_USUARIOS");
		}
		if (contFunc > 0) {
			identity.addRole("FUNCIONALIDADES");
		}
	}

}
